<template>
  <div class="responsive-table-container">
    <!-- 桌面端表格视图 -->
    <div class="desktop-view" :class="{ 'mobile-hidden': isMobileDevice }">
      <el-table
        :data="data"
        :loading="loading"
        v-bind="tableProps"
        @selection-change="handleSelectionChange"
        @row-click="handleRowClick"
      >
        <template v-for="column in columns" :key="column.prop">
          <el-table-column
            v-bind="getColumnProps(column)"
            :prop="column.prop"
            :label="column.label"
            :width="column.width"
            :min-width="column.minWidth"
            :fixed="column.fixed"
            :sortable="column.sortable"
          >
            <template #default="scope" v-if="column.slot">
              <slot :name="column.slot" v-bind="scope"></slot>
            </template>
          </el-table-column>
        </template>

        <slot name="append"></slot>
      </el-table>

      <!-- 分页 -->
      <div class="pagination-wrapper" v-if="pagination">
        <el-pagination
          v-model:current-page="pagination.current_page"
          v-model:page-size="pagination.page_size"
          :page-sizes="pagination.page_sizes || [10, 20, 50, 100]"
          :total="pagination.total"
          :layout="getPaginationLayout()"
          v-bind="paginationProps"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </div>

    <!-- 移动端卡片视图 -->
    <div class="mobile-view" v-show="isMobileDevice">
      <div class="mobile-header" v-if="showMobileHeader">
        <div class="header-left">
          <slot name="mobile-header-left"></slot>
        </div>
        <div class="header-right">
          <el-button
            v-if="showSelectionActions && selectedRows.length > 0"
            size="small"
            @click="clearSelection"
          >
            取消选择
          </el-button>
          <el-button
            size="small"
            @click="refreshData"
          >
            <el-icon><Refresh /></el-icon>
          </el-button>
        </div>
      </div>

      <div class="mobile-cards" v-loading="loading">
        <div
          v-for="(item, index) in data"
          :key="getRowKey(item, index)"
          class="mobile-card"
          :class="{ selected: isRowSelected(item) }"
          @click="handleCardClick(item, index)"
        >
          <!-- 选择框 -->
          <div class="card-checkbox" v-if="showSelection">
            <el-checkbox
              :model-value="isRowSelected(item)"
              @change="handleRowSelection(item, $event)"
            />
          </div>

          <!-- 主要内容 -->
          <div class="card-content">
            <!-- 标题行 -->
            <div class="card-title" v-if="titleColumn">
              <slot
                :name="titleColumn.slot"
                :row="item"
                :index="index"
              >
                <div class="title-content">
                  <span class="title-text">{{ getColumnValue(item, titleColumn) }}</span>
                  <div class="title-tags">
                    <el-tag
                      v-for="tag in getRowTags(item, titleColumn)"
                      :key="tag.text"
                      :type="tag.type"
                      size="small"
                    >
                      {{ tag.text }}
                    </el-tag>
                  </div>
                </div>
              </slot>
            </div>

            <!-- 信息行 -->
            <div class="card-info">
              <div
                v-for="column in infoColumns"
                :key="column.prop"
                class="info-item"
              >
                <span class="info-label">{{ column.label }}：</span>
                <span class="info-value">
                  <slot
                    :name="column.slot"
                    :row="item"
                    :column="column"
                    :index="index"
                  >
                    {{ getColumnValue(item, column) }}
                  </slot>
                </span>
              </div>
            </div>

            <!-- 额外信息 -->
            <div class="card-extra" v-if="extraColumns.length > 0">
              <div
                v-for="column in extraColumns"
                :key="column.prop"
                class="extra-item"
              >
                <div class="extra-label">{{ column.label }}</div>
                <div class="extra-value">
                  <slot
                    :name="column.slot"
                    :row="item"
                    :column="column"
                    :index="index"
                  >
                    {{ getColumnValue(item, column) }}
                  </slot>
                </div>
              </div>
            </div>
          </div>

          <!-- 操作按钮 -->
          <div class="card-actions" v-if="actionButtons.length > 0">
            <el-button
              v-for="action in getRowActions(item)"
              :key="action.key"
              :type="action.type"
              :size="action.size || 'small'"
              :icon="action.icon"
              :disabled="action.disabled"
              @click.stop="handleAction(action, item, index)"
            >
              {{ action.text }}
            </el-button>
          </div>
        </div>
      </div>

      <!-- 移动端分页 -->
      <div class="mobile-pagination" v-if="pagination">
        <el-pagination
          v-model:current-page="pagination.current_page"
          v-model:page-size="pagination.page_size"
          :total="pagination.total"
          layout="prev, pager, next"
          small
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>

      <!-- 批量操作栏 -->
      <div
        class="mobile-actions-bar"
        v-if="showSelectionActions && selectedRows.length > 0"
      >
        <div class="actions-info">
          已选择 {{ selectedRows.length }} 项
        </div>
        <div class="actions-buttons">
          <el-button
            v-for="action in batchActions"
            :key="action.key"
            :type="action.type"
            size="small"
            @click="handleBatchAction(action)"
          >
            {{ action.text }}
          </el-button>
        </div>
      </div>

      <!-- 空状态 -->
      <div v-if="!loading && data.length === 0" class="mobile-empty">
        <el-empty
          :description="emptyText || '暂无数据'"
          :image-size="80"
        />
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { useResponsive } from '@/composables/useResponsive'
import { Refresh } from '@element-plus/icons-vue'
import type { TableColumnCtx } from 'element-plus'

interface Column {
  prop: string
  label: string
  width?: string | number
  minWidth?: string | number
  fixed?: boolean | 'left' | 'right'
  sortable?: boolean | 'custom'
  slot?: string
  type?: string
  mobile?: {
    title?: boolean
    info?: boolean
    extra?: boolean
    hidden?: boolean
  }
}

interface Action {
  key: string
  text: string
  type?: string
  icon?: any
  size?: string
  disabled?: boolean | ((row: any) => boolean)
  show?: boolean | ((row: any) => boolean)
}

interface BatchAction {
  key: string
  text: string
  type?: string
}

interface Props {
  data: any[]
  columns: Column[]
  loading?: boolean
  pagination?: {
    current_page: number
    page_size: number
    total: number
    page_sizes?: number[]
  }
  tableProps?: Record<string, any>
  paginationProps?: Record<string, any>
  titleColumn?: string
  showSelection?: boolean
  showMobileHeader?: boolean
  showSelectionActions?: boolean
  actionButtons?: Action[]
  batchActions?: BatchAction[]
  emptyText?: string
  rowKey?: string | ((row: any) => string)
}

const props = withDefaults(defineProps<Props>(), {
  loading: false,
  showSelection: false,
  showMobileHeader: true,
  showSelectionActions: true,
  actionButtons: () => [],
  batchActions: () => [],
  emptyText: ''
})

const emit = defineEmits<{
  selectionChange: [selection: any[]]
  rowClick: [row: any, column: any, event: Event]
  sizeChange: [size: number]
  currentChange: [current: number]
  refresh: []
  action: [action: Action, row: any, index: number]
  batchAction: [action: BatchAction]
}>()

const { isMobileDevice } = useResponsive()

// 响应式状态
const selectedRows = ref<any[]>([])

// 计算属性
const titleColumn = computed(() => {
  if (props.titleColumn) {
    return props.columns.find(col => col.prop === props.titleColumn)
  }
  return props.columns.find(col => col.mobile?.title) || props.columns[0]
})

const infoColumns = computed(() => {
  return props.columns.filter(col => {
    if (col.prop === titleColumn.value?.prop) return false
    if (col.mobile?.hidden) return false
    if (col.mobile?.title) return false
    if (col.mobile?.extra) return false
    return col.type !== 'selection' && col.type !== 'index'
  }).slice(0, 4) // 移动端最多显示4个信息字段
})

const extraColumns = computed(() => {
  return props.columns.filter(col => col.mobile?.extra)
})

// 方法
const getColumnProps = (column: Column) => {
  const { slot, mobile, ...props } = column
  return props
}

const getColumnValue = (row: any, column: Column): any => {
  if (column.prop) {
    const keys = column.prop.split('.')
    let value = row
    for (const key of keys) {
      value = value?.[key]
    }
    return value
  }
  return ''
}

const getRowKey = (row: any, index: number): string => {
  if (props.rowKey) {
    return typeof props.rowKey === 'function' ? props.rowKey(row) : row[props.rowKey]
  }
  return index.toString()
}

const isRowSelected = (row: any): boolean => {
  const rowKey = getRowKey(row, props.data.indexOf(row))
  return selectedRows.value.some(item => getRowKey(item, props.data.indexOf(item)) === rowKey)
}

const handleRowSelection = (row: any, selected: boolean) => {
  if (selected) {
    if (!isRowSelected(row)) {
      selectedRows.value.push(row)
    }
  } else {
    selectedRows.value = selectedRows.value.filter(
      item => getRowKey(item, props.data.indexOf(item)) !== getRowKey(row, props.data.indexOf(row))
    )
  }
  emit('selectionChange', selectedRows.value)
}

const handleSelectionChange = (selection: any[]) => {
  selectedRows.value = selection
  emit('selectionChange', selection)
}

const clearSelection = () => {
  selectedRows.value = []
  emit('selectionChange', [])
}

const getRowTags = (row: any, column: Column): Array<{ text: string, type: string }> => {
  // 可以根据列的配置返回不同的标签
  const value = getColumnValue(row, column)
  const tags = []

  // 示例：根据状态返回不同颜色的标签
  if (column.prop === 'status') {
    const statusMap: Record<string, string> = {
      pending: 'warning',
      success: 'success',
      error: 'danger',
      info: 'info'
    }
    tags.push({
      text: value,
      type: statusMap[value] || 'info'
    })
  }

  return tags
}

const getRowActions = (row: any): Action[] => {
  return props.actionButtons.filter(action => {
    if (typeof action.show === 'function') {
      return action.show(row)
    }
    return action.show !== false
  }).map(action => ({
    ...action,
    disabled: typeof action.disabled === 'function' ? action.disabled(row) : action.disabled
  }))
}

const getPaginationLayout = (): string => {
  if (isMobileDevice.value) {
    return 'prev, pager, next'
  }
  return 'total, sizes, prev, pager, next, jumper'
}

const handleCardClick = (row: any, index: number) => {
  // 模拟表格的行点击事件
  emit('rowClick', row, {}, new Event('click') as any)
}

const handleAction = (action: Action, row: any, index: number) => {
  emit('action', action, row, index)
}

const handleBatchAction = (action: BatchAction) => {
  emit('batchAction', action)
}

const handleSizeChange = (size: number) => {
  emit('sizeChange', size)
}

const handleCurrentChange = (current: number) => {
  emit('currentChange', current)
}

const refreshData = () => {
  emit('refresh')
}

const handleRowClick = (row: any, column: any, event: Event) => {
  emit('rowClick', row, column, event)
}

// 监听器
watch(() => props.data, () => {
  // 数据变化时清空选择
  if (selectedRows.value.length > 0) {
    clearSelection()
  }
})
</script>

<style scoped>
.responsive-table-container {
  width: 100%;
}

.desktop-view {
  width: 100%;
}

.mobile-view {
  width: 100%;
}

.mobile-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 16px;
  background: var(--el-bg-color);
  border-bottom: 1px solid var(--el-border-color-lighter);
  margin-bottom: 16px;
  border-radius: 8px;
}

.mobile-cards {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.mobile-card {
  background: var(--el-bg-color);
  border: 1px solid var(--el-border-color-lighter);
  border-radius: 12px;
  padding: 16px;
  transition: all 0.3s ease;
  cursor: pointer;
}

.mobile-card:hover {
  border-color: var(--el-color-primary-light-5);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
}

.mobile-card.selected {
  border-color: var(--el-color-primary);
  background: var(--el-color-primary-light-9);
}

.card-checkbox {
  position: absolute;
  top: 16px;
  right: 16px;
}

.card-content {
  margin-bottom: 12px;
}

.card-title {
  margin-bottom: 12px;
}

.title-content {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 12px;
}

.title-text {
  font-size: 16px;
  font-weight: 600;
  color: var(--el-text-color-primary);
  flex: 1;
}

.title-tags {
  display: flex;
  gap: 4px;
  flex-shrink: 0;
}

.card-info {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.info-item {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  font-size: 14px;
}

.info-label {
  color: var(--el-text-color-secondary);
  font-weight: 500;
  min-width: 80px;
  flex-shrink: 0;
}

.info-value {
  color: var(--el-text-color-primary);
  flex: 1;
}

.card-extra {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--el-border-color-lighter);
}

.extra-item {
  margin-bottom: 8px;
}

.extra-item:last-child {
  margin-bottom: 0;
}

.extra-label {
  font-size: 12px;
  color: var(--el-text-color-secondary);
  margin-bottom: 4px;
}

.extra-value {
  font-size: 14px;
  color: var(--el-text-color-primary);
}

.card-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.card-actions .el-button {
  flex: 1;
  min-width: 80px;
}

.mobile-pagination {
  display: flex;
  justify-content: center;
  margin-top: 20px;
}

.mobile-actions-bar {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  background: var(--el-bg-color);
  border-top: 1px solid var(--el-border-color-lighter);
  padding: 12px 16px;
  z-index: 100;
  display: flex;
  justify-content: space-between;
  align-items: center;
  box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.05);
}

.actions-info {
  font-size: 14px;
  color: var(--el-text-color-primary);
}

.actions-buttons {
  display: flex;
  gap: 8px;
}

.mobile-empty {
  padding: 40px 20px;
  text-align: center;
}

/* 响应式调整 */
@media (max-width: 480px) {
  .mobile-card {
    padding: 12px;
  }

  .title-text {
    font-size: 15px;
  }

  .info-item {
    font-size: 13px;
  }

  .card-actions .el-button {
    font-size: 12px;
    padding: 6px 12px;
  }

  .mobile-actions-bar {
    padding: 8px 12px;
  }

  .actions-info {
    font-size: 13px;
  }
}

/* 安全区域适配 */
@supports (padding: max(0px)) {
  .mobile-actions-bar {
    padding-bottom: max(12px, env(safe-area-inset-bottom));
  }
}

/* 状态样式补充 */
.mobile-card.status-pending {
  border-left: 4px solid var(--el-color-warning);
}

.mobile-card.status-success {
  border-left: 4px solid var(--el-color-success);
}

.mobile-card.status-error {
  border-left: 4px solid var(--el-color-danger);
}

.mobile-card.status-info {
  border-left: 4px solid var(--el-color-info);
}
</style>